#ifndef LIST_H
#define LIST_H
#include "comm/types.h"

// 链表节点数据结构
typedef struct _list_node_t
{
    struct _list_node_t *pre;
    struct _list_node_t *next;
}list_node_t;

static inline void list_node_init(list_node_t * node)
{
    node->pre = node->next = 0;
}

static inline list_node_t* list_node_pre(list_node_t * node)
{
    return node->pre;
}

static inline list_node_t* list_node_next(list_node_t * node)
{
    return node->next;
}

typedef struct _list_t
{
    list_node_t * first;
    list_node_t * last;
    int count;
}list_t;

// 链表初始化
void list_init(list_t * list);
// 链表检查
void list_isOK(void);
// 链表头插
void list_insert_first(list_t * list, list_node_t * node);
// 链表尾插
void list_insert_last(list_t * list, list_node_t * node);
// 链表头删
list_node_t * list_remove_first(list_t * list);
// 链表删除特定节点
list_node_t * list_remove_node(list_t * list, list_node_t * node);

static inline int list_is_empty(list_t * list)
{
    return (list->count == 0);
}

static inline int list_count(list_t * list)
{
    return list->count;
}

static inline list_node_t* list_first(list_t * list)
{
    return list->first;
}

static inline list_node_t* list_last(list_t * list)
{
    return list->last;
}

// 已知 结构体中node_name的地址，求该name_name相对于整个结构体偏移
// 将地址0 转换为该结构体，取0地址的node_name属性，取地址
// 就是node_name 相对于地址0 的偏移
#define offset_in_parent(parent_type, node_name) \
    ( (uint32_t)&(((parent_type*)0)->node_name) )

// 当前属性地址 - 属性在结构体中的偏移 = 结构体的起始地址

#define parent_addr(node, parent_type, node_name) \
    ( (uint32_t)node - offset_in_parent(parent_type, node_name) )

// 结果转换为结构体指针
// 如果node为空，就返回0
#define list_node_parent(node, parent_type, node_name) \
    ( node ? ( parent_type* )parent_addr(node, parent_type, node_name) : 0 )
#endif // !LIST_H